home *** CD-ROM | disk | FTP | other *** search
- /* hAWK_Interface.c : hAWK dialog interface */
- /* Copyright © 1986, 1988, 1989 1991 the Free Software Foundation, Inc.
- * This file is part of GAWK, the GNU implementation of the
- * AWK Progamming Language, modified for the Macintosh (also called hAWK).
- * GAWK is free software; you can redistribute or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or any later version.
- * GAWK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with GAWK; see the file "COPYING hAWK". If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- * Written for THINK C 4 on the Macintosh by Ken Earle (Dynabyte) Aug 1991.
- */
-
- /* Code to synthesize a command line based on user's choices in the
- main hAWK dialog. Mouse-driven, except for variables that one wishes
- to be set on the command line - these must be typed in.
-
- Program options: choose from a list of all hAWK programs in the
- folder "hAWK programs", or some other programs via a standard SFGetFile dialog.
- "Library" files may also be added - the parser treats them as being appended
- to the main program, but for the sake of sanity they should contain only
- function definitions.
-
- Variables options: not very fancy, just type in "var=value" (not including the quotes)
- in the dialog for variables.
-
- Input options: here's where the Mac really shines - hAWK has generalized options for
- input which allow a program to be run on different input without altering the
- dialog setup - that's why its possible and useful to save the setup associated
- with a particular hAWK program
- - Specific input file; the one "fixed" option, allows user to pick one particular
- input file as input
- - Selected front text / All of front text; takes as input all or the selected part
- of the text window that happens to be in front when hAWK is called
- - MFS selected files; takes as input all files selected for multi-file operation
- in the calling application - usually multi-file searching.
-
- Save settings: saves the dialog options with the hAWK program. Especially useful
- for restoring the input option.
-
- An "About" button displays copysquawk about hAWK/gawk/awk/nawk.
-
- Rev Dec 5/92: Run button always drawn bold in a more-general way,
- Set Variables button emboldened if variables are already present for a program.
-
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- //#include <fcntl.h>
- #include <string.h>
- #include <setjmp.h>
- #include "CodeResHelper.h" /* TMalloc etc */
- #include "CodeResource.h"
- #include "AppCodeComm.h"
-
- extern void *alloca(unsigned short size);
- extern void DumpZoneList(void);
- extern void DisposeProgress(void); /* hAWK_prompt.c */
-
- /* buffer holding position of long jump */
- jmp_buf envBuf;
-
- static short argc;
- static char **argv;
- static short NUMARGVS = 500; /* Was a #define, now variable */
-
- short gInputError; /* Not used yet */
-
- /* interface constants and struct recording user choices */
- #define NUMLIBS 10 /* max number of libraries */
- #define NUMVARSETS 10 /* max number of "command line" variables */
- typedef struct HawkSetup
- {
- short inputType; /* input file or "metafile" specification */
- Boolean showOut, selectOut; /* passed back to calling application */
- char *progname; /* the hAWK program */
- char *libraryname[NUMLIBS];
- char *varsetting[NUMVARSETS];
- char *inputname; /* optional, if one specific file selected */
- short progVRefNum; /* not saved to disk - for currently selected program*/
- short defaultVRefNum; /* not saved, for the folder "hAWK programs" */
- short otherVRefNum; /* for "unlisted" program */
- } HawkSetup;
- /* global record of user choices */
- HawkSetup HS;
-
- /* Current popup items. Note the current selection for the input popup is
- recorded in HS,inputType. */
- static short mainProgMenuNum = 1,
- libraryMenuNum = 1;
-
- /* User choices can be saved with hAWK program for next run */
- #define HAWKID 1011 /* resource id, type 'HAWK' */
-
- /* Dialog to set up a hAWK run.
- */
- #define HawkDlogID 405
- /* OK is 1, Cancel is 2 */
- #define SaveHawkSetup 3
- #define ProgramStat 5
- #define LibraryStat 6
- #define InputStat 7
- #define VariableButton 8
- #define ShowOut 9
- #define SelectOut 10
- #define ProgramPopup 11
- #define LibraryPopup 12
- #define InputPopup 13
- #define AboutHawk 14
- #define RunUserItem 15
- #define VarUserItem 16
-
- /* popups */
- #define MainProgramID 187
- #define LibraryID 188
- #define InputID 189
-
- /* The "Take input from:" popup varies accoring to which extensions
- are supplied by the application: GetFrontText_Ext is nonnull only if
- it is appropriate to take input from a front text window - note this
- will be null even if the application supports the extension, in the case
- where no text file is open at the time this code resource is called.
- GetNextFileToSearch_Ext is nonnull if the application supports selecting
- multiple files somehow, the most common use being for multi-file
- searching. Again this will be passed in as NULL if there are no files
- selected at the time of the call.
- */
- typedef struct InputPopupItems
- {
- short frontSelected, /* user's selected text in front text window */
- frontAll, /* all of text in front window */
- multiSelected, /* multiple files, as specified within application */
- specificFile; /* pick one with SFGetFIle */
- } InputPopupItems, *InPopItemPtr;
- static InputPopupItems inPop;
-
- /* from AWK_MAIN.C */
- extern short AWKmain(short argc, char **argv);
-
- /* Functions defined in this file: */
- short InvokeHAWK(void); /* the external call - see Code_Main.c */
- /* Dialog management, "command line" creation: */
- Boolean DoHawkDialog(void);
- void CreateHawkProgramResourcePopups(void);
- void CreateInputPopup(void);
- long FindHawkProgramFolder(char *curvolName, char *hawkFolderName);
- void AddProgramsToMenu(char *curvolName, long theDirID, MenuHandle theMenu);
- void AlphaAppendMenu(MenuHandle theMenu, short lowPoint, char *name);
- short AlphaMenuPos(char *name, MenuHandle theMenu, short highPoint, short lowPoint);
- short MenuCompare(char *name, MenuHandle theMenu, short index);
- short PtrLenPascalCompare(Ptr spatPtr, short patLen, Ptr stargetPtr);
- void DestroyHawkPopups(void);
- pascal void HawkPopProc(WindowPtr wdPtr, short item);
- pascal void ButtonProc(WindowPtr wdPtr, short item);
- void SetPopupMark(short theMenuID, short newItem);
- void ResetHS(DialogPtr dPtr);
- void LoadHawkDlogFromHS(DialogPtr dPtr, Boolean progToo);
- void GetMenuEntryFromFullName(char *name, char *filename);
- void SaveInvocation(DialogPtr dPtr, char *name);
- Handle CreateHawkProgramResource(DialogPtr dPtr); /* from HS, mostly */
- Boolean ReadHAWKResource(char *name); /* to HS */
- void ConvertRsrcToHS(Handle h);
- void ClearHS(void);
- void RedrawItem(DialogPtr dPtr, short itemHit);
- void RedrawDialog(DialogPtr dPtr);
- Boolean DoVarDialog(DialogPtr hAWKDLOGdPtr);
- void LoadExistingVarsToDlog(DialogPtr dPtr);
- short BadVarFormat(DialogPtr dPtr);
- void GetHawkProgramName(DialogPtr dPtr, short item);
- void GetHawkLibraryName(short menuItem);
- void GetInputFileName(void);
- Boolean GetCommandLineFromDlogResult(void);
- char *CreateStdIn(Boolean wholeFile);
- Boolean GetInputsFromMFS(void);
- /* Error handling, cleanup after run: */
- void JumpOnHAWKError(short inputErrorNumber);
- void CleanUpAfterHAWK(void);
- void HandleHAWKError(void);
- void DoExiting(void);
-
- short InvokeHAWK(void)
- {
-
- //_fmode = O_TEXT; /* default is binary */
- InitTempCodeMemory(); /* see CodeResource_Helper.c */
-
- if (!DoHawkDialog())
- {
- DoExiting();
- return(-1); /* user cancelled, most likely, or out of memory */
- }
- SetWatchCursor();
- /* If hAWK fails, it long-jumps back to here
- and setjmp returns non-zero. */
- if (!setjmp(envBuf))
- {
- AWKmain(argc, argv);
- CleanUpAfterHAWK();
- //_exiting(1);
- /* show result if wanted */
- DoExiting();
- if (HS.showOut)
- {
- if (HS.selectOut)
- return(2);
- return(1);
- }
- return(0);
- }
- else
- {
- CleanUpAfterHAWK();
- //_exiting(1);
- HandleHAWKError();
- DoExiting();
- return(-2);
- }
- }
-
-
-
- Boolean DoHawkDialog()
- {
- MenuHandle theMenu;
- DialogPtr dPtr;
- Handle theHandle;
- Rect theBox;
- Point pt;
- long aLong;
- short theID, menuItem;
- short kind, itemHit, badChar, theType;
- char mText[64];
- Boolean checkValue;
- UserItemUPP HawkPopProcUPP;
- UserItemUPP ButtonProcUPP;
-
- if (!GetAndAlignDialog(HawkDlogID))
- return(FALSE);
- dPtr = GetNewDialog(HawkDlogID, NULL, (WindowPtr)-1L);
- CreateHawkProgramResourcePopups();
- /* attach procs for popups */
- HawkPopProcUPP = NewUserItemProc(HawkPopProc);
- GetDItem(dPtr, ProgramPopup, &kind, &theHandle, &theBox);
- SetDItem(dPtr,ProgramPopup, kind, (Handle)HawkPopProcUPP, &theBox);
- GetDItem(dPtr, LibraryPopup, &kind, &theHandle, &theBox);
- SetDItem(dPtr,LibraryPopup, kind, (Handle)HawkPopProcUPP, &theBox);
- GetDItem(dPtr, InputPopup, &kind, &theHandle, &theBox);
- SetDItem(dPtr,InputPopup, kind, (Handle)HawkPopProcUPP, &theBox);
- /*...and buttons */
- ButtonProcUPP = NewUserItemProc(ButtonProc);
- GetDItem(dPtr, RunUserItem, &kind, &theHandle, &theBox);
- SetDItem(dPtr,RunUserItem, kind, (Handle)ButtonProcUPP, &theBox);
- GetDItem(dPtr, VarUserItem, &kind, &theHandle, &theBox);
- SetDItem(dPtr,VarUserItem, kind, (Handle)ButtonProcUPP, &theBox);
- ((WindowPeek)(dPtr))->refCon = 0; /* used to record if variables exist */
- /* init HawkSetup */
- HS.progname = HS.inputname = NULL;
- for (itemHit = 0; itemHit < NUMLIBS; ++itemHit)
- HS.libraryname[itemHit] = NULL;
- for (itemHit = 0; itemHit < NUMVARSETS; ++itemHit)
- HS.varsetting[itemHit] = NULL;
- ResetHS(dPtr); /* clears popup contents too */
- SetPopupMark(InputID, HS.inputType);
- ShowWindow(dPtr);
- SetPort(dPtr);
- /* Initially Run and Save Settings are disabled - no program yet */
- HiliteDlgControl(dPtr, 1, 255);
- HiliteDlgControl(dPtr, SaveHawkSetup, 255);
- InitCursor();
- itemHit = 99;
- while (itemHit > 2) /* ie not Run/Cancel */
- {
- ModalDialog(NULL, &itemHit);
- switch (itemHit)
- {
- case SaveHawkSetup: /* enabled only if program has been picked */
- if (HS.progname)
- SaveInvocation(dPtr, HS.progname);
- /* else very odd error - ignore */
- break;
- case ShowOut:
- case SelectOut:
- GetCheck (dPtr, itemHit, &checkValue);
- SetCheck (dPtr, itemHit, !checkValue);
- break;
- case ProgramPopup:
- /* Treat any pick from this menu as request
- to change main program */
- GetDItem(dPtr, ProgramStat, &kind, &theHandle, &theBox);
- InvertRect(&theBox);
- pt.v = theBox.top;
- pt.h = theBox.right;
- LocalToGlobal(&pt);
- theMenu = GetMHandle(MainProgramID);
- aLong = PopUpMenuSelect(theMenu, pt.v, pt.h, 1);
- theID = HiWord(aLong);
- menuItem = LoWord(aLong);
- InvertRect(&theBox);
- if (menuItem > 0) /* get program and any saved settings */
- {
- GetHawkProgramName(dPtr, menuItem);
- SetPopupMark(InputID, HS.inputType);
- RedrawDialog(dPtr);
- }
- break;
- case LibraryPopup:
- /* Either "Select library" - add a library;
- or the name of a library - delete it. */
- GetDItem(dPtr, LibraryStat, &kind, &theHandle, &theBox);
- InvertRect(&theBox);
- pt.v = theBox.top;
- pt.h = theBox.right;
- LocalToGlobal(&pt);
- theMenu = GetMHandle(LibraryID);
- aLong = PopUpMenuSelect(theMenu, pt.v, pt.h, 1);
- theID = HiWord(aLong);
- menuItem = LoWord(aLong);
- InvertRect(&theBox);
- if (menuItem > 0) /* get or delete library */
- {
- GetHawkLibraryName(menuItem);
- RedrawItem(dPtr, itemHit);
- }
- break;
- case InputPopup:
- GetDItem(dPtr, InputStat, &kind, &theHandle, &theBox);
- InvertRect(&theBox);
- pt.v = theBox.top;
- pt.h = theBox.right;
- LocalToGlobal(&pt);
- theMenu = GetMHandle(InputID);
- aLong = PopUpMenuSelect(theMenu, pt.v, pt.h, HS.inputType);
- theID = HiWord(aLong);
- menuItem = LoWord(aLong);
- InvertRect(&theBox);
- if (menuItem > 0)
- HS.inputType = menuItem;
- if (menuItem == inPop.frontSelected)
- {
- ;
- }
- else if (menuItem == inPop.frontAll)
- {
- ;
- }
- else if (menuItem == inPop.multiSelected)
- {
- ;
- }
- else if (menuItem == inPop.specificFile)
- {
- GetInputFileName();
- }
- if (menuItem > 0 && menuItem != inPop.specificFile)
- {
- if (HS.inputname)
- {
- DisposPtr(HS.inputname);
- HS.inputname = NULL;
- SetItem(theMenu, inPop.specificFile, (StringPtr)"\pSelect input file...");
- }
- }
- if (menuItem > 0)
- {
- SetPopupMark(InputID, HS.inputType);
- RedrawItem(dPtr, itemHit);
- }
- break;
- case VariableButton:
- if (!DoVarDialog(dPtr)) /* serious error if FALSE */
- {
- itemHit = 2;
- SysBeep(2);
- goto NeverMind;
- }
- RedrawDialog(dPtr);
- break;
- case AboutHawk:
- OKStopAlert("Copyright © 1991, Free Software Foundation.\r\
- GNU Awk and hAWK come with ABSOLUTELY NO WARRANTY. This is free software, and \
- you are welcome to distribute it under the terms of the GNU General \
- Public License, which covers both the warranty information and the \
- terms for redistribution.\r\
- You should have received a copy of the GNU General Public License along \
- with this program (see COPYING hAWK); if not, write to the Free Software Foundation, Inc., \
- 675 Mass Ave, Cambridge, MA 02139, USA.");
- break;
- }
- }
- NeverMind:
- // TEST ONLY DELETE
- // DisposeRoutineDescriptor(HawkPopProcUPP);
- // DisposeRoutineDescriptor(ButtonProcUPP);
-
- /* cancelled? */
- if (itemHit == 2) /* cancel */
- {
- if (HS.inputname)
- DisposPtr(HS.inputname);
- if (HS.progname)
- DisposPtr(HS.progname);
- for (itemHit = 0; itemHit < NUMLIBS; ++itemHit)
- {
- if (HS.libraryname[itemHit])
- DisposPtr(HS.libraryname[itemHit]);
- }
- for (itemHit = 0; itemHit < NUMVARSETS; ++itemHit)
- {
- if (HS.varsetting[itemHit])
- DisposPtr(HS.varsetting[itemHit]);
- }
- DisposDialog(dPtr);
- DestroyHawkPopups();
- return(FALSE);
- }
- /* translate to "commmand" line */
- if(!GetCommandLineFromDlogResult())
- {
- DisposDialog(dPtr);
- DestroyHawkPopups();
- return(FALSE);
- }
- GetCheck (dPtr, ShowOut, &checkValue);
- HS.showOut = checkValue;
- GetCheck (dPtr, SelectOut, &checkValue);
- HS.selectOut = checkValue;
- DisposDialog(dPtr);
- DestroyHawkPopups();
- return(TRUE);
- }
-
- /* Called for each run.
- The input selection popup depends on what extensions have
- been passed in for this run. A largely pointless exercise in
- dynamically maintaining a menu, yet Apple disapproves of
- disabling items in a popup menu, so this approach has the
- virtue of being not-officially-frowned-upon. */
- void CreateHawkProgramResourcePopups()
- {
- MenuHandle theMenu;
-
- CreateInputPopup();
-
- theMenu = NewMenu(LibraryID, (StringPtr)"\pLibraries");
- AppendMenu(theMenu, (StringPtr)"\pSelect library...");
- InsertMenu(theMenu, -1);
-
- theMenu = NewMenu(InputID, (StringPtr)"\pInput");
- if (HasGetFrontText())
- {
- inPop.frontSelected = 1;
- inPop.frontAll = 2;
- AppendMenu(theMenu, (StringPtr)"\pFront text selection");
- AppendMenu(theMenu, (StringPtr)"\pAll of front text");
- }
- else
- {
- inPop.frontSelected = inPop.frontAll = 0;
- }
- if (HasGetNextMultiFile())
- {
- if (inPop.frontSelected)
- inPop.multiSelected = 3;
- else
- inPop.multiSelected = 1;
- AppendMenu(theMenu, (StringPtr)"\pMFS selected files");
- }
- else
- inPop.multiSelected = 0;
- if (inPop.frontSelected || inPop.multiSelected)
- {
- if (inPop.multiSelected == 3) /* all present */
- inPop.specificFile = 5;
- else if (inPop.multiSelected == 1) /* front options missing */
- inPop.specificFile = 3;
- else /* multi missing, therefore hasgetfront */
- inPop.specificFile = 4;
- AppendMenu(theMenu, (StringPtr)"\p-");
- }
- else
- {
- inPop.specificFile = 1;
- }
- /* This option is always available */
- AppendMenu(theMenu, (StringPtr)"\pSelect input file...");
- InsertMenu(theMenu, -1);
- }
-
- void CreateInputPopup()
- {
- MenuHandle theMenu;
- char curvolName[32];
- long theDirID;
-
- theMenu = NewMenu(MainProgramID, (StringPtr)"\pMainProgram");
- AppendMenu(theMenu, (StringPtr)"\pSelect unlisted program...");
-
- /* When hAWK is called, the current working folder is the one
- containing hAWK - search it for the folder "hAWK programs.
- If found, add all TEXT files whose names begin with $ to the
- program popup, in alpha order. */
- if (theDirID = FindHawkProgramFolder(curvolName, (char *)"\phAWK programs"))
- AddProgramsToMenu(curvolName, theDirID, theMenu);
- InsertMenu(theMenu, -1);
- }
-
- long FindHawkProgramFolder(char *curvolName, char *hawkFolderName)
- {
- HFileInfo myCPB;
- WDPBRec theParms;
- char fName[32];
- long theDirID;
- short codeVRefNum, index = 1, len;
- OSErr err;
-
-
- GetVol(NULL, &codeVRefNum);
- /* Extract "\pVolName:" and dirID for code resource folder */
- theParms.ioNamePtr = (StringPtr)(curvolName);
- theParms.ioVRefNum = codeVRefNum;
- theParms.ioWDIndex = 0;
- theParms.ioWDProcID = 0;
- if (PBGetWDInfo(&theParms,false))
- {
- OKStopAlert("Bad working directory");
- return(0L);
- }
- len = curvolName[0];
- curvolName[len + 1] = ':';
- curvolName[0] = len + 1;
-
- theDirID = theParms.ioWDDirID;
-
- myCPB.ioNamePtr = (StringPtr)fName;
- myCPB.ioVRefNum = theParms.ioWDVRefNum;
- do
- {
- myCPB.ioFDirIndex = index;
- myCPB.ioDirID = theDirID;
- if ((err = PBGetCatInfo((CInfoPBPtr)&myCPB, FALSE)) == noErr)
- {
- if (((myCPB.ioFlAttrib>>4) & 0x01) == 1) /* a folder */
- {
- if (PEqualStrs((Byte *)fName, (Byte *)hawkFolderName))
- return(myCPB.ioDirID);
- }
- }
- ++index;
- } while (err == noErr);
- /* OKStopAlert("hawk program folder not found"); if you're testing */
- return(0L);
- }
-
- void AddProgramsToMenu(char *curvolName, long theDirID, MenuHandle theMenu)
- {
- HFileInfo myCPB;
- WDPBRec theParms;
- HVolumeParam vParms;
- char fName[32], volName[32];
- short index = 1, theVolRef, vRefNum;
- OSErr err;
- Boolean firstAdd = TRUE;
-
- /* Some shenanigans to open working directory for code resources */
- BlockMove(curvolName, volName, 32);
- vParms.ioCompletion = NULL;
- vParms.ioNamePtr = (StringPtr)(volName);
- vParms.ioVRefNum = -32768;
- vParms.ioVolIndex = -1;
- if (PBHGetVInfo((HParmBlkPtr)&vParms, FALSE))
- theVolRef = 0;
- else
- theVolRef = vParms.ioVRefNum;
- theParms.ioCompletion = NULL;
- theParms.ioVRefNum = theVolRef;
- theParms.ioNamePtr = NULL;
- theParms.ioWDDirID = theDirID;
- theParms.ioWDProcID = 'ERIK';
- if (PBOpenWD(&theParms, FALSE)) /* IM IV pg 158 */
- vRefNum = 0;
- else
- vRefNum = theParms.ioVRefNum;
-
- theParms.ioNamePtr = NULL;
- theParms.ioVRefNum = vRefNum;
- theParms.ioWDIndex = 0;
- theParms.ioWDProcID = 0;
- if (PBGetWDInfo(&theParms,false))
- return;
- HS.defaultVRefNum = vRefNum; /* saved away, folder is left open */
-
- myCPB.ioNamePtr = (StringPtr)fName;
- myCPB.ioVRefNum = theParms.ioWDVRefNum;
- do
- {
- myCPB.ioFDirIndex = index;
- myCPB.ioDirID = theDirID;
- if ((err = PBGetCatInfo((CInfoPBPtr)&myCPB, FALSE)) == noErr)
- {
- if (((myCPB.ioFlAttrib>>4) & 0x01) != 1) /* a file */
- {
- /* fName holds name of file */
- /* Is it the right kind of file? */
- if (myCPB.ioFlFndrInfo.fdType == 'TEXT'
- && fName[1] == '$')
- {
- if (firstAdd)
- {
- AppendMenu(theMenu, (StringPtr)"\p-");
- AppendMenu(theMenu, (StringPtr)"\p-");
- firstAdd = FALSE;
- }
- AlphaAppendMenu(theMenu, 4, fName);
- }
- }
- }
- ++index;
- } while (err == noErr);
- if (firstAdd) /* none added */
- {
- theParms.ioVRefNum = vRefNum;
- PBCloseWD(&theParms, FALSE);
- }
- }
-
- void AlphaAppendMenu(MenuHandle theMenu, short lowPoint, char *name)
- {
- short newItemNum,
- highPoint = CountMItems(theMenu);
-
-
- newItemNum = AlphaMenuPos(name, theMenu, highPoint, lowPoint);
- if (newItemNum > 0)
- {
- /*error duplicate - unlikely for file list. */
- return;
- }
- else
- newItemNum = -newItemNum;
- InsMenuItem(theMenu, (StringPtr)"\pa", newItemNum - 1);
- SetItem(theMenu, newItemNum, (StringPtr)name);
- }
-
- /* Binary search existing menu for match against nameptr; if
- match return lowPoint:highPoint. If no match let n = where name would
- be inserted, range lowPoint:highPoint+1, return -n. For insertion, do
- InsMenuItem(theMenu, (StringPtr)"\pa", n - 1); -see just above.
- */
- short AlphaMenuPos(char *name, MenuHandle theMenu, short highPoint, short lowPoint)
- {
- short index;
-
- if (highPoint < lowPoint)
- return(-lowPoint);
-
- do
- {
- index = (lowPoint + highPoint)/2;
- if (MenuCompare(name, theMenu, index) < 0)
- highPoint = index - 1;
- else
- lowPoint = index + 1;
- } while (MenuCompare(name, theMenu, index) && lowPoint <= highPoint);
- if (!MenuCompare(name, theMenu, index)) /* a hit */
- return(index);
- /* lowPoint went "one too far", ie it is number that name will be after insertion */
- return(-lowPoint);
- }
-
- short MenuCompare(char *name, MenuHandle theMenu, short index)
- {
- char itemStr[64];
-
- GetItem(theMenu, index, (StringPtr)itemStr);
- /* Fudge, both mark and item strs are pascal, but warp to ptr/len vs pascal.
- Sorry folks, doing it this way because I had the tested code already. */
- return(PtrLenPascalCompare(name + 1L, name[0], itemStr));
- }
-
- /* Compare, for ptr, len vs pascal strings.
- Compare pattern with target, returning number
- reflecting alphabetical rather than ascii order.
- */
- typedef Byte *BPtr;
- short PtrLenPascalCompare(Ptr spatPtr, short patLen, Ptr stargetPtr)
- {
- BPtr patPtr = (BPtr)spatPtr,
- patEndPtr = patPtr + patLen,
- curPtr = (BPtr)stargetPtr + 1,
- curEndPtr = curPtr + (unsigned short)(stargetPtr[0]);
- short i, j;
-
- while (patPtr < patEndPtr && curPtr < curEndPtr && *patPtr == *curPtr)
- {
- ++patPtr;
- ++curPtr;
- }
-
- if (patPtr == patEndPtr && curPtr == curEndPtr) /* exact match */
- return(0);
- if (patPtr == patEndPtr && curPtr != curEndPtr) /* pattern too short */
- return(-1);
- if (patPtr != patEndPtr && curPtr == curEndPtr) /* starget too short */
- return(1);
-
- /* true miscompare within string */
- i = (short)*patPtr;
- j = (short)*curPtr;
- /* sequence: nonalpha, AaBbCc...Zz */
- /* 'A' = 65, 'a' = 97; move 'U' to 'U'*2 + 256, 'u' to 'u'*2 + 193 */
- /* 'A' -> 386, 'B' -> 388, 'a' -> 387, 'b' -> 389 etc */
- if ('A' <= i && i <= 'Z')
- i = i*2 + 256;
- else if ('a' <= i && i <= 'z')
- i = i*2 + 193;
- if ('A' <= j && j <= 'Z')
- j = j*2 + 256;
- else if ('a' <= j && j <= 'z')
- j = j*2 + 193;
- return(i - j);
- }
-
- void DestroyHawkPopups()
- {
- MenuHandle theMenu;
-
- theMenu = GetMHandle(MainProgramID);
- if (!theMenu)
- return;
- DeleteMenu(MainProgramID);
- DisposeMenu(theMenu);
-
- theMenu = GetMHandle(LibraryID);
- if (!theMenu)
- return;
- DeleteMenu(LibraryID);
- DisposeMenu(theMenu);
-
- theMenu = GetMHandle(InputID);
- if (!theMenu)
- return;
- DeleteMenu(InputID);
- DisposeMenu(theMenu);
- }
-
- /* Somebody's watching, so draw in the popup menus. */
- pascal void HawkPopProc(WindowPtr wdPtr, short item)
- {
- GrafPtr savePort;
- short kind, menuNum, i, n, markChar;
- Handle theHandle;
- MenuHandle theMenu;
- Rect box;
- Byte mText[64];
-
- GetPort(&savePort);
- SetPort (wdPtr);
- if (item == LibraryPopup)
- {
- theMenu = GetMHandle(LibraryID);
- menuNum = 1;
- }
- else if (item == ProgramPopup || item == InputPopup)
- {
- if (item == ProgramPopup)
- theMenu = GetMHandle(MainProgramID);
- else
- theMenu = GetMHandle(InputID);
- n = CountMItems(theMenu);
- for (i = 1; i <= n; ++i)
- {
- GetItemMark(theMenu, i, &markChar);
- if (markChar == ' ')
- break;
- }
- if (i <= n)
- menuNum = i;
- else
- menuNum = 1;
- }
- else return;
-
- GetDItem(wdPtr, item, &kind, &theHandle, &box);
- GetItem(theMenu, menuNum, mText);
- EraseRect(&box);
- TextBox(&(mText[1]),(unsigned char)(mText[0]),&box,teJustLeft);
- box.left -= 1;
- box.top -= 1;
- box.right += 1;
- box.bottom += 1;
- FrameRect(&box);
- MoveTo(box.left + 1, box.bottom);
- LineTo(box.right, box.bottom);
- MoveTo(box.right, box.top + 1);
- LineTo(box.right, box.bottom);
- SetPort(savePort);
- }
-
- pascal void ButtonProc(WindowPtr wdPtr, short item)
- {
- GrafPtr savePort;
- PenState savePen;
- Handle h;
- Rect theBox;
- short theType, ovalSize, i;
- Pattern myWhite, myGray;
- Boolean needsFrame;
-
- GetDItem(wdPtr,item,&theType,&h,&theBox);
- GetPort(&savePort);
- SetPort(wdPtr);
- GetPenState(&savePen);
- PenNormal();
- PenSize(2,2);
- if (item == RunUserItem)
- InsetRect(&theBox,-3,-3);
- else if (item == VarUserItem)
- {
- needsFrame =(Boolean)(((WindowPeek)(wdPtr))->refCon);
- if (needsFrame)
- {
- for (i = 0; i < 8; i += 2)
- myGray.pat[i] = 0xAA;
- for (i = 1; i < 8; i += 2)
- myGray.pat[i] = 0x55;
- PenPat(&myGray);
- }
- else
- {
- for (i = 0; i < 8; ++i)
- myWhite.pat[i] = 0;
- PenPat(&myWhite);
- }
- InsetRect(&theBox,-2,-2);
-
- }
- ovalSize = (theBox.bottom + 8 - theBox.top) / 2;
- FrameRoundRect(&theBox,ovalSize,ovalSize);
- SetPenState(&savePen);
- SetPort(savePort);
- }
-
- /* A space character is used to mark the currently-selected item,
- avoiding the horror of attempting to access global variables
- within the pascal callback above, within a CODE resource. */
- void SetPopupMark(short theMenuID, short newItem)
- {
- short i, n, markChar;
- MenuHandle theMenu;
-
- theMenu = GetMHandle(theMenuID);
- n = CountMItems(theMenu);
- for (i = 1; i <= n; ++i)
- {
- GetItemMark(theMenu, i, &markChar);
- if (markChar == ' ')
- {
- if (i == newItem)
- return;
- else
- SetItemMark(theMenu, i, 0);
- }
- else if (i == newItem)
- {
- markChar = ' ';
- SetItemMark(theMenu, i, markChar);
- }
- }
- }
-
- void ResetHS(DialogPtr dPtr)
- {
- MenuHandle theMenu;
- short itemHit, numItems;
-
- SetCheck (dPtr, ShowOut, TRUE);
- SetCheck (dPtr, SelectOut, TRUE);
- mainProgMenuNum = libraryMenuNum = HS.inputType = 1;
- HS.showOut = TRUE;
- HS.selectOut = TRUE;
- if (HS.progname)
- {
- DisposPtr(HS.progname);
- HS.progname = NULL;
- }
- if (HS.inputname)
- {
- DisposPtr(HS.inputname);
- HS.inputname = NULL;
- }
- for (itemHit = 0; itemHit < NUMLIBS; ++itemHit)
- {
- if (HS.libraryname[itemHit])
- {
- DisposPtr(HS.libraryname[itemHit]);
- HS.libraryname[itemHit] = NULL;
- }
- }
- for (itemHit = 0; itemHit < NUMVARSETS; ++itemHit)
- {
- if (HS.varsetting[itemHit])
- {
- DisposPtr(HS.varsetting[itemHit]);
- HS.varsetting[itemHit] = NULL;
- }
- }
- theMenu = GetMHandle(MainProgramID);
- SetItem(theMenu, 1, (StringPtr)"\pSelect unlisted program...");
- theMenu = GetMHandle(LibraryID);
- itemHit = CountMItems(theMenu);
- while (--itemHit > 0)
- DelMenuItem(theMenu, 1);
- theMenu = GetMHandle(InputID);
- SetItem(theMenu, inPop.specificFile, (StringPtr)"\pSelect input file...");
- }
-
- /* Set visual display and menus in Hawk dialog, and at end
- convert all strings from pascal to c format. Note vars are not
- shown here (but their strings are converted).
- Assumes menus have been reset.
- If progToo is FALSE, being called in response to HawkDlog main program popup
- which retrieves and sets progname directly from open dialog, and also
- sets menu entry. If progToo is TRUE, then have received progname from resource
- and should then handle progname here - currently not needed.
- */
- void LoadHawkDlogFromHS(DialogPtr dPtr, Boolean progToo)
- {
- MenuHandle theMenu;
- short i, numItems = 1;
- char filename[32];
-
- /* Set the checks */
- SetCheck (dPtr, ShowOut, HS.showOut);
- SetCheck (dPtr, SelectOut, HS.selectOut);
-
- if (progToo)
- {
- PtoCstr((StringPtr)HS.progname);
- GetMenuEntryFromFullName(HS.progname, filename);
- theMenu = GetMHandle(MainProgramID);
- SetItem(theMenu, 1, (StringPtr)filename);
- }
- /* variables - nothing shown, just convert strings */
- for (i = 0; i < NUMVARSETS; ++i)
- {
- if (HS.varsetting[i])
- PtoCstr((StringPtr)HS.varsetting[i]);
- else
- break;
- }
- /* dialog's refCon used to tell ButtonProc if variables exist */
- if (i)
- ((WindowPeek)(dPtr))->refCon = 1;
- else
- ((WindowPeek)(dPtr))->refCon = 0;
- /* libraries - append to menu and convert strings */
- theMenu = GetMHandle(LibraryID);
- for (i = 0; i < NUMLIBS; ++i)
- {
- if (HS.libraryname[i])
- {
- PtoCstr((StringPtr)HS.libraryname[i]);
- GetMenuEntryFromFullName(HS.libraryname[i], filename);
- if (numItems == 1)
- {
- InsMenuItem(theMenu, (StringPtr)"\pa", 0);
- SetItem(theMenu, 1, (StringPtr)filename);
- InsMenuItem(theMenu, (StringPtr)"\p-", 1);
- }
- else
- {
- InsMenuItem(theMenu, (StringPtr)"\pa", numItems-2);
- SetItem(theMenu, numItems-1, (StringPtr)filename);
- }
- ++numItems;
-
- }
- else
- break;
- }
- /* input - set input file name */
- if (HS.inputType == inPop.specificFile)
- {
- if (HS.inputname)
- {
- PtoCstr((StringPtr)HS.inputname);
- GetMenuEntryFromFullName(HS.inputname, filename);
- if (filename[0])
- {
- theMenu = GetMHandle(InputID);
- SetItem(theMenu, inPop.specificFile, (StringPtr)filename);
- }
- }
- }
- }
-
- /* Extract pstr filename from end of cstr full path name */
- void GetMenuEntryFromFullName(char *name, char *filename)
- {
- short len = strlen(name);
- Ptr endPtr = name + len, startPtr = endPtr ;
-
- while (startPtr >= name)
- {
- if (*startPtr == ':')
- break;
- --startPtr;
- }
- ++startPtr;
- if (startPtr >= endPtr)
- {
- filename[0] = 0;
- return;
- }
- filename[0] = endPtr - startPtr;
- BlockMove(startPtr, filename+1, filename[0]);
- }
-
- void SaveInvocation(DialogPtr dPtr, char *name)
- {
- short saveVol, refNum, vRefNum;
- Handle rHdle;
- char filename[32];
- short len = strlen(name);
- Ptr endPtr = name + len, startPtr = endPtr ;
-
- while (startPtr >= name)
- {
- if (*startPtr == ':')
- break;
- --startPtr;
- }
- ++startPtr;
- if (startPtr >= endPtr) return;
- filename[0] = endPtr - startPtr;
- BlockMove(startPtr, filename+1, filename[0]);
-
- vRefNum = HS.progVRefNum;
- if (!vRefNum) return;
-
- if (GetVol(NULL, &saveVol))
- saveVol = 0;
-
- SetVol(NULL, vRefNum);
- if (refNum = OpenOrCreateResourceFork((StringPtr)filename))
- {
- if (rHdle = CreateHawkProgramResource(dPtr))
- {
- DeleteAllExistingRsrcs('HAWK', HAWKID);
- AddResource(rHdle, 'HAWK', HAWKID, (StringPtr)"");
- }
- CloseResFile (refNum);
- }
- /* Reset volume to original one */
- if (saveVol)
- SetVol(NULL, saveVol);
- /* Make sure changes are written out */
- FlushVol(NULL, vRefNum);
- }
-
- /* Note all strings are c strings coming in (and going out).
- Only HS.inputType requires special attention: it is the menu
- item number corresponding to the currently-selected input
- option, and varies according to which extensions from the
- calling application have currently been made available. To avoid
- confusion, the number saved is the one that would be used if all
- extensions were present. */
- Handle CreateHawkProgramResource(DialogPtr dPtr)
- {
- Handle resH;
- Ptr tPtr;
- long size;
- short numLibs = 0, numVars = 0, i, len;
-
- if (!(HS.progname)) return(NULL);
- /* precalc size of handle */
- size = 8;
- size += strlen(HS.progname) + 1;
- for (i = 0; i <= NUMLIBS; ++i)
- {
- if (!(HS.libraryname[i]))
- break;
- size += strlen(HS.libraryname[i]) + 1;
- ++numLibs;
- }
- for (i = 0; i < NUMVARSETS; ++i)
- {
- if (!(HS.varsetting[i]))
- break;
- size += strlen(HS.varsetting[i]) + 1;
- ++numVars;
- }
- if (HS.inputType == inPop.specificFile)
- size += strlen(HS.inputname) + 1;
-
- GetCheck(dPtr, ShowOut, &(HS.showOut));
- GetCheck(dPtr, SelectOut, &(HS.selectOut));
-
- resH = NewHandle(size);
- if (MemError() != noErr)
- return(NULL);
- tPtr = *resH;
- len = HS.inputType;
- if (inPop.specificFile < 5) /* adjust recorded input type */
- {
- /* Boost value of HS.inputType to what it would be if all
- input options were present - here we know that either the two
- front text options or the multifile option or both are missing. */
- if (HS.inputType == 1)
- {
- if (inPop.frontSelected == 0 && inPop.multiSelected == 0)
- HS.inputType = 5;
- else if (inPop.frontSelected == 0)
- HS.inputType = 3;
- else
- HS.inputType = 1;
- }
- else if (HS.inputType == 3) /* implies inPop.frontSelected == 0 */
- HS.inputType = 5;
- else if (HS.inputType == 4) /* implies inPop.multiSelected == 0 */
- HS.inputType = 5;
- /* note HS.inputType == 2 needs no adjusting */
- }
- BlockMove((Ptr)(&HS.inputType), tPtr, 2);
- HS.inputType = len;
- tPtr += 2;
- BlockMove((Ptr)(&HS.showOut), tPtr, 1);
- ++tPtr;
- BlockMove((Ptr)(&HS.selectOut), tPtr, 1);
- ++tPtr;
- BlockMove((Ptr)(&numLibs), tPtr, 2);
- tPtr += 2;
- BlockMove((Ptr)(&numVars), tPtr, 2);
- tPtr += 2;
- /* Save text items in pascal format for easier read/write/setup */
- len = strlen(HS.progname);
- *tPtr++ = len;
- BlockMove(HS.progname, tPtr, len);
- tPtr += len;
- for (i = 0; i < NUMLIBS; ++i)
- {
- if (!(HS.libraryname[i]))
- break;
- len = strlen(HS.libraryname[i]);
- *tPtr++ = len;
- BlockMove(HS.libraryname[i], tPtr, len);
- tPtr += len;
- }
- for (i = 0; i < NUMVARSETS; ++i)
- {
- if (!(HS.varsetting[i]))
- break;
- len = strlen(HS.varsetting[i]);
- *tPtr++ = len;
- BlockMove(HS.varsetting[i], tPtr, len);
- tPtr += len;
- }
- if (HS.inputType == inPop.specificFile)
- {
- len = strlen(HS.inputname);
- *tPtr++ = len;
- BlockMove(HS.inputname, tPtr, len);
- }
- return(resH);
- }
-
- /* Open res fork of Hawk pgm, copy setup info to HS. */
- Boolean ReadHAWKResource(char *name) /* to HS */
- {
- short saveVol, refNum, vRefNum;
- Handle rHdle;
- char filename[32];
- short len = strlen(name);
- Ptr endPtr = name + len, startPtr = endPtr ;
-
- while (startPtr >= name)
- {
- if (*startPtr == ':')
- break;
- --startPtr;
- }
- ++startPtr;
- if (startPtr >= endPtr) return(FALSE);
- filename[0] = endPtr - startPtr;
- BlockMove(startPtr, filename+1, filename[0]);
-
- vRefNum = HS.progVRefNum;
- if (!vRefNum) return(FALSE);
-
- if (GetVol(NULL, &saveVol))
- saveVol = 0;
- SetVol(NULL, vRefNum);
-
- if ((refNum = OpenResFile((StringPtr)filename)) != -1)
- {
- rHdle = Get1Resource ('HAWK', HAWKID);
- if (!rHdle)
- {
- CloseResFile(refNum);
- if (saveVol)
- SetVol(NULL, saveVol);
- return(FALSE);
- }
- /* Convert raw rsrc to HS */
- ConvertRsrcToHS(rHdle);
- ReleaseResource(rHdle);
- CloseResFile(refNum);
- }
- /* Restore default volume if any */
- if (saveVol)
- SetVol(NULL, saveVol);
- if (refNum == -1)
- return(FALSE);
- return(TRUE);
- }
-
- /* Retrieve HawkSetup data, with strings in pascal format for the moment.
- Set progname only if it has not already been set.
- HS.inputType was saved as though all extensions present - if
- currently some extensions are missing then inputType needs adjusting.
- The default for a missing choice is inPop.specificFile. */
- void ConvertRsrcToHS(Handle h)
- {
- Ptr tPtr, endPtr;
- long size;
- short numLibs, numVars, i, len, recordedInputType;
-
- //MoveHHi(h);
- HLock(h);
- tPtr = *h;
- size = GetHandleSize(h);
- endPtr = tPtr + size;
- BlockMove(tPtr, (Ptr)(&HS.inputType), 2);
- recordedInputType = HS.inputType;
- /* adjust inputType if extension(s) missing */
- if (inPop.specificFile < 5) /* adjust input type */
- {
- if (HS.inputType == 1 || HS.inputType == 2)
- {
- /* the frontSelected/frontAll options, not valid if
- inPop.frontSelected == 0 */
- if (inPop.frontSelected == 0)
- HS.inputType = inPop.specificFile;
- }
- else if (HS.inputType == 3)
- {
- /* multiSelected option - not valid if inPop.multiSelected == 0,
- and adjust if inPop.frontSelected == 0 */
- if (inPop.multiSelected == 0)
- HS.inputType = inPop.specificFile;
- else if (inPop.frontSelected == 0)
- HS.inputType = inPop.multiSelected;
- }
- else if (HS.inputType == 5) /* always valid */
- {
- if (inPop.frontSelected == 0 && inPop.multiSelected == 0)
- HS.inputType = 1;
- else if (inPop.frontSelected == 0)
- HS.inputType = 3;
- else
- HS.inputType = 4;
- }
- /* note 4 not possible - in the full menu it's a dashed line */
- }
- tPtr += 2;
- BlockMove(tPtr, (Ptr)(&HS.showOut), 1);
- ++tPtr;
- BlockMove(tPtr, (Ptr)(&HS.selectOut), 1);
- ++tPtr;
- BlockMove(tPtr, (Ptr)(&numLibs), 2);
- tPtr += 2;
- BlockMove(tPtr, (Ptr)(&numVars), 2);
- tPtr += 2;
- len = *tPtr++;
- if (tPtr + len > endPtr)
- goto NoGo;
- if (!(HS.progname))
- {
- HS.progname = NewPtr(len+1);
- if (MemError() != noErr)
- goto NoGo;
- HS.progname[0] = len;
- BlockMove(tPtr, HS.progname+1, len);
- }
- tPtr += len;
- for (i = 0; i < numLibs; ++i)
- {
- len = *tPtr++;
- if (tPtr + len > endPtr)
- goto NoGo;
- HS.libraryname[i] = NewPtr(len+1);
- if (MemError() != noErr)
- goto NoGo;
- HS.libraryname[i][0] = len;
- BlockMove(tPtr, HS.libraryname[i]+1, len);
- tPtr += len;
- }
- for (i = 0; i < numVars; ++i)
- {
- len = *tPtr++;
- if (tPtr + len > endPtr)
- goto NoGo;
- HS.varsetting[i] = NewPtr(len+1);
- if (MemError() != noErr)
- goto NoGo;
- HS.varsetting[i][0] = len;
- BlockMove(tPtr, HS.varsetting[i]+1, len);
- tPtr += len;
- }
- if (recordedInputType == 5)
- {
- len = *tPtr++;
- if (tPtr + len > endPtr)
- goto NoGo;
- HS.inputname = NewPtr(len+1);
- if (MemError() != noErr)
- goto NoGo;
- HS.inputname[0] = len;
- BlockMove(tPtr, HS.inputname+1, len);
- }
- HUnlock(h);
- return;
- NoGo:
- HUnlock(h);
- ClearHS();
- return;
- }
-
- void ClearHS()
- {
- short itemHit;
-
- HS.showOut = TRUE;
- HS.selectOut = TRUE;
- if (HS.inputname)
- {
- DisposPtr(HS.inputname);
- HS.inputname = NULL;
- }
- for (itemHit = 0; itemHit < NUMLIBS; ++itemHit)
- {
- if (HS.libraryname[itemHit])
- {
- DisposPtr(HS.libraryname[itemHit]);
- HS.libraryname[itemHit] = NULL;
- }
- }
- for (itemHit = 0; itemHit < NUMVARSETS; ++itemHit)
- {
- if (HS.varsetting[itemHit])
- {
- DisposPtr(HS.varsetting[itemHit]);
- HS.varsetting[itemHit] = NULL;
- }
- }
- }
-
- void RedrawItem(DialogPtr dPtr, short itemHit)
- {
- GrafPtr savePort;
- short kind;
- Handle theHandle;
- MenuHandle theMenu;
- Rect box;
-
- GetPort(&savePort);
- SetPort (dPtr);
- GetDItem(dPtr, itemHit, &kind, &theHandle, &box);
- InvalRect(&box);
- SetPort(savePort);
- }
-
- void RedrawDialog(DialogPtr dPtr)
- {
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort (dPtr);
- InvalRect(&dPtr->portRect);
- SetPort(savePort);
- }
-
- #define VARDlog 407
- #define FirstVARID 4
-
- /* The variables dialog. Needs a bit more error-checking. */
- Boolean DoVarDialog(DialogPtr hAWKDLOGdPtr)
- {
- DialogPtr dPtr;
- short itemHit, theType, i, j;
- char varStr[100];
-
- if (!GetAndAlignDialog(VARDlog))
- return(FALSE);
- dPtr = GetNewDialog(VARDlog, NULL, (WindowPtr)-1L);
- LoadExistingVarsToDlog(dPtr);
- ShowWindow(dPtr);
- FrameDialogItem(dPtr,1);
- InitCursor();
- itemHit = 99;
- while (itemHit > 2)
- {
- ModalDialog(NULL, &itemHit);
- /* Check length if you think someone might type > 99 characters */
- if (itemHit == 1) /* check format */
- {
- if ((itemHit = BadVarFormat(dPtr)) > 3)
- {
- SysBeep(2);
- SelIText(dPtr, itemHit, 0, 32767);
- }
- }
- }
- if (itemHit == 2) /* cancel */
- {
- DisposDialog(dPtr);
- return(TRUE);
- }
- /* Record new variable settings */
- j = 0;
- for (i = FirstVARID; i < FirstVARID + NUMVARSETS; ++i)
- {
- GetEText(dPtr, i, (StringPtr) varStr);
- if (varStr[0])
- {
- HS.varsetting[j] = NewPtr(varStr[0] + 3);
- if (MemError() != noErr)
- return(FALSE);
- HS.varsetting[j][0] = varStr[0] + 2;
- BlockMove(varStr+1, HS.varsetting[j] + 3, varStr[0]);
- /* stick -v in front */
- HS.varsetting[j][1] = '-';
- HS.varsetting[j][2] = 'v';
- PtoCstr((StringPtr)HS.varsetting[j]);
- ++j;
- }
- }
- /* dialog's refCon used to tell ButtonProc if variables exist */
- if (j)
- ((WindowPeek)(hAWKDLOGdPtr))->refCon = 1;
- else
- ((WindowPeek)(hAWKDLOGdPtr))->refCon = 0;
- /* null out any left over */
- while (j < NUMVARSETS)
- {
- HS.varsetting[j++] = NULL;
- }
- DisposDialog(dPtr);
- return(TRUE);
- }
-
- void LoadExistingVarsToDlog(DialogPtr dPtr)
- {
- short itemHit;
-
- /* set the fields before showing */
- for (itemHit = 0; itemHit < NUMVARSETS; ++itemHit)
- {
- if (HS.varsetting[itemHit] && strlen(HS.varsetting[itemHit]))
- {
- /* Minor complication - have -v in front */
- CtoPstr(HS.varsetting[itemHit]+2);
- SetEText(dPtr, FirstVARID + itemHit,
- (StringPtr) (HS.varsetting[itemHit]+2));
- PtoCstr((StringPtr)HS.varsetting[itemHit]+2);
- }
- else
- SetEText(dPtr, FirstVARID + itemHit,
- (StringPtr) "\p");
- }
- }
-
- /* Return 1 if all vars OK, var item number if one is bad (>= 4) */
- short BadVarFormat(DialogPtr dPtr)
- {
- short i, j, len;
- char varStr[100];
-
- /* Variable format is varname=something. This is a quick check. */
- for (i = FirstVARID; i < FirstVARID + NUMVARSETS; ++i)
- {
- GetEText(dPtr, i, (StringPtr) varStr);
- if (varStr[0])
- {
- len = varStr[0];
- for (j = 1; j <= len; ++j)
- {
- if (varStr[j] == '=')
- break;
- }
- if (j >= len || j == 1)
- return(i);
- }
- }
- return(1);
- }
-
- void GetHawkProgramName(DialogPtr dPtr, short item)
- {
- MenuHandle theMenu;
- Point where;
- SFReply reply;
- SFTypeList types;
- long len;
- short numTypes;
- Boolean userLocated;
-
- if (item == 1)
- {
- /* display dialog, get program name and input file name */
- types[0] = 'TEXT';
- types[1] = 'RRRS';
- numTypes = 2;
- GetDlogOrigin (getDlgID, &where);
- SFGetFile (where, (StringPtr)"\p", NULL, numTypes, types, NULL, &reply);
- if (!reply.good)
- return;
- userLocated = TRUE;
- }
- else /* either listed or unlisted program - the unlisted one is number 3 */
- {
- if (item == mainProgMenuNum) /* nothing new */
- return;
- theMenu = GetMHandle(MainProgramID);
- GetItem(theMenu, item, (StringPtr)(reply.fName));
- userLocated = FALSE;
- }
- /* reset HS and dialog */
- ResetHS(dPtr);
-
- HS.progname = NewPtr(256);
- if (MemError() != noErr)
- {
- HS.progVRefNum = 0;
- MemoryAlert();
- HiliteDlgControl(dPtr, 1, 255);
- HiliteDlgControl(dPtr, SaveHawkSetup, 255);
- return;
- }
- if (userLocated)
- HS.progVRefNum = reply.vRefNum;
- else if (item == 3)
- HS.progVRefNum = HS.otherVRefNum;
- else
- HS.progVRefNum = HS.defaultVRefNum;
- if (userLocated)
- mainProgMenuNum = 3;
- else
- mainProgMenuNum = item;
- AppendPStr((Byte *)(FullPathNameFromVRefNum(HS.progVRefNum,(Byte *)(HS.progname))),
- (Byte *)(reply.fName));
- /* stick -f in front */
- BlockMove(HS.progname+1, HS.progname + 3, 253);
- HS.progname[0] += 2;
- HS.progname[1] = '-';
- HS.progname[2] = 'f';
- SetPtrSize(HS.progname, HS.progname[0]+1);
- PtoCstr((StringPtr)HS.progname); /* also done by LoadHawkDlogFromHS */
- /* Restore saved invocation */
- if (ReadHAWKResource(HS.progname))
- LoadHawkDlogFromHS(dPtr, FALSE); /* Boolean progToo */
- theMenu = GetMHandle(MainProgramID);
- if (userLocated)
- SetItem(theMenu, 3, reply.fName);
- /* Enable Run and SaveSettings buttons */
- HiliteDlgControl(dPtr, 1, 0);
- HiliteDlgControl(dPtr, SaveHawkSetup, 0);
- if (item == 1)
- item = 3;
- SetPopupMark(MainProgramID, item);
-
- /* Redraw done by caller */
- }
-
- /* Delete/add library. Add new item just before dash. */
- void GetHawkLibraryName(short menuItem)
- {
- MenuHandle theMenu;
- Point where;
- SFReply reply;
- SFTypeList types;
- long len;
- short numTypes, numItems, which, i;
- Boolean hasLib;
-
- theMenu = GetMHandle(LibraryID);
- numItems = CountMItems(theMenu);
- if (menuItem < numItems) /* delete */
- {
- DelMenuItem(theMenu, menuItem);
- if (numItems == 3)
- DelMenuItem(theMenu, 1); /* take out the dash */
- which = menuItem-1;
- if (HS.libraryname[which])
- {
- DisposPtr(HS.libraryname[which]);
- HS.libraryname[which] = NULL;
- /* consolidate pointers */
- if (which == NUMLIBS-1) return;
- BlockMove((Ptr)(&(HS.libraryname[which])),
- (Ptr)(&(HS.libraryname[which+1])),
- sizeof(char *) * (NUMLIBS-1 - which));
- }
- return;
- }
- /* add new library at end of list */
- which = 0;
-
- /* display dialog, get program name and input file name */
- types[0] = 'TEXT';
- types[1] = 'RRRS';
- numTypes = 2;
- GetDlogOrigin (getDlgID, &where);
- SFGetFile (where, (StringPtr)"\p", NULL, numTypes, types, NULL, &reply);
- if (!reply.good)
- return;
- HS.libraryname[which] = NewPtr(256);
- if (MemError() != noErr)
- {
- MemoryAlert();
- return;
- }
- AppendPStr((Byte *)(FullPathNameFromVRefNum(reply.vRefNum,(Byte *)(HS.libraryname[which]))),
- (Byte *)(reply.fName));
- /* stick -f in front */
- BlockMove(HS.libraryname[which]+1, HS.libraryname[which] + 3, 253);
- HS.libraryname[which][0] += 2;
- HS.libraryname[which][1] = '-';
- HS.libraryname[which][2] = 'f';
- PtoCstr((StringPtr)HS.libraryname[which]);
- /* Set menu */
- if (numItems == 1)
- {
- InsMenuItem(theMenu, (StringPtr)"\pa", 0);
- SetItem(theMenu, 1, reply.fName);
- InsMenuItem(theMenu, (StringPtr)"\p-", 1);
- }
- else
- {
- InsMenuItem(theMenu, (StringPtr)"\pa", numItems-2);
- SetItem(theMenu, numItems-1, reply.fName);
- }
- }
-
- void GetInputFileName()
- {
- MenuHandle theMenu;
- Point where;
- SFReply reply;
- SFTypeList types;
- long len;
- short numTypes;
-
- /* display dialog, get program name and input file name */
- types[0] = 'TEXT';
- types[1] = 'RRRS';
- numTypes = 2;
- GetDlogOrigin (getDlgID, &where);
- SFGetFile (where, (StringPtr)"\p", NULL, numTypes, types, NULL, &reply);
- if (!reply.good)
- return;
-
- if (HS.inputname)
- {
- DisposPtr(HS.inputname);
- HS.inputname = NULL;
- }
- HS.inputname = NewPtr(256);
- if (MemError() != noErr)
- {
- MemoryAlert();
- return;
- }
- AppendPStr((Byte *)(FullPathNameFromVRefNum(reply.vRefNum,(Byte *)(HS.inputname))),
- (Byte *)(reply.fName));
- PtoCstr((StringPtr)HS.inputname);
- /* Set menu */
- theMenu = GetMHandle(InputID);
- SetItem(theMenu, inPop.specificFile, reply.fName);
- }
-
- /* Command line for awk proper, generated from user
- dialog choices and variable entries.
- HAWK -fProgname -fLibraries -vVariables -- inputfiles
- */
- Boolean GetCommandLineFromDlogResult()
- {
- long len;
- short i;
-
- if (!(HS.progname))
- {
- SysBeep(2); /* - can't do much without a program. */
- return(FALSE);
- }
- if (HS.inputType == inPop.specificFile && !(HS.inputname))
- {
- /* A suspicious case, arrived at either thru:
- - pick "Specific file..." option for input, and then cancel
- to, in effect, select the empty file; or
- - saved input option does not exist for this run, have defaulted
- to this case.
- Since a hAwk program can still do things in its BEGIN block even with
- no input file, allow the "no input at all" option to proceed. */
- ;
- }
- argc = 0;
- argv = (char **)NewPtr(sizeof(char *) * NUMARGVS);
- if (MemError() != noErr)
- {
- CleanUpAfterHAWK();
- return(FALSE);
- }
- /* hawk name always as first arg */
- len = strlen(gacc.thisCodeName);
- argv[argc] = NewPtr(len+1);
- if (!argv[argc])
- return(FALSE);
- BlockMove(gacc.thisCodeName, argv[argc], len+1);
- ++argc;
-
- argv[argc] = HS.progname;
- ++argc;
- for (i = 0; i < NUMLIBS; ++i)
- {
- if (!(HS.libraryname[i]))
- break;
- argv[argc] = HS.libraryname[i];
- ++argc;
- }
- /* variables */
- for (i = 0; i < NUMVARSETS; ++i)
- {
- if (!(HS.varsetting[i]))
- break;
- argv[argc] = HS.varsetting[i];
- ++argc;
- }
- /* the -- */
- len = 2;
- argv[argc] = NewPtr(len+1);
- if (MemError() != noErr)
- {
- CleanUpAfterHAWK();
- return(FALSE);
- }
- BlockMove("--", argv[argc], len+1);
- ++argc;
- /* lastly, get input file if any - note hAWK can still do things even
- if no input file specified in command line. */
- if (HS.inputType == inPop.frontSelected || HS.inputType == inPop.frontAll)
- {
- argv[argc] = CreateStdIn(HS.inputType == inPop.frontAll);
- if (!argv[argc])
- {
- CleanUpAfterHAWK();
- return(FALSE);
- }
- ++argc;
- }
- else if (HS.inputType == inPop.multiSelected)
- {
- if (!GetInputsFromMFS())
- {
- CleanUpAfterHAWK();
- return(FALSE);
- }
- }
- else if (HS.inputType == inPop.specificFile && HS.inputname)
- {
- argv[argc] = HS.inputname;
- ++argc;
- }
- return(TRUE);
- }
-
- /* If user wants the input to be whatever is in the front text file,
- get a copy of the text and write it the the file used for standard input. */
- char *CreateStdIn(Boolean wholeFile)
- {
- Ptr copyOfName;
- Handle hText;
- long len;
- OSErr IOResult;
- short refNum;
-
- /* anything? */
- if (HasGetFrontText())
- {
- hText = GetFrontText(wholeFile);
- }
- else
- hText = NewHandle(0);
- if (!hText)
- return(NULL);
-
- /* save to standard input file */
- /* Delete the file. We don't care if there's an error */
- FSDelete((StringPtr)gacc.stdInFileNameP, 0);
-
- /* Now try to create it. '????' is the creator. Report the file error, if any */
- if (IOResult = Create((StringPtr)gacc.stdInFileNameP, 0, '????', 'TEXT'))
- {
- DisposHandle(hText);
- OKStopAlert("Standard input file could not be created.");
- return(NULL);
- }
-
- if (IOResult = FSOpen ((StringPtr)gacc.stdInFileNameP, 0, &refNum))
- {
- DisposHandle(hText);
- OKStopAlert("Standard input file could not be opened.");
- return(NULL);
- }
- len = GetHandleSize(hText);
- if (IOResult = FSWrite (refNum, &len, *hText))
- {
- FSClose (refNum);
- DisposHandle(hText);
- OKStopAlert("Standard input file could not be written to.");
- return(NULL);
- }
- FSClose (refNum);
- DisposHandle(hText);
- /* return ptr to copy of gacc.stdInFileName if success, or NULL */
- len = strlen(gacc.stdInFileName);
- copyOfName = NewPtr(len+1);
- if (!copyOfName)
- return(NULL);
- BlockMove(gacc.stdInFileName, copyOfName, len+1);
- return(copyOfName);
- }
-
- /* Build list of files from multi-file search or equivalent selection.
- This version, concoct full path name for each file.
- Next version, use dirID and save much space. */
- Boolean GetInputsFromMFS()
- {
- char **newArgv;
- Byte *tempPtr, *endPtr;
- short whichPane, index, vRefNum, lastvrefnum = 0;
- char fileName[32];
-
- if (!HasGetNextMultiFile()) return(FALSE);
- /* determine which file to search next */
- whichPane = -1;
- GetNextMultiFile(&whichPane, &index, &vRefNum, fileName, FALSE);
- if (index < 0)
- return(FALSE);
- while (index >= 0)
- {
- tempPtr = (Byte *)NewPtr(256);
- if (MemError() != noErr)
- return(FALSE);
- /* This is a prime target for optimizing, since it does a lot of
- disk-pounding to retrieve the full path name. Detecting a run of
- the same vrefnum certainly helps.*/
- if (vRefNum != lastvrefnum) /* do it the hard way */
- AppendPStr((Byte *)(FullPathNameFromVRefNum(vRefNum, tempPtr)),
- (Byte *)(fileName));
- else
- {
- BlockMove(argv[argc-1], (Ptr)tempPtr, 256);
- CtoPstr((Ptr)tempPtr);
- /* strip previous file name */
- endPtr = tempPtr + tempPtr[0];
- while (*endPtr != ':')
- --endPtr;
- tempPtr[0] = (unsigned char)(endPtr - tempPtr);
- /* append new file name */
- AppendPStr(tempPtr, (Byte *)(fileName));
- }
- SetPtrSize((Ptr)tempPtr, tempPtr[0]+1);
- PtoCstr((StringPtr)tempPtr);
- argv[argc++] = (Ptr)tempPtr;
- lastvrefnum = vRefNum;
- GetNextMultiFile(&whichPane, &index, &vRefNum, fileName, FALSE);
- if (index >= 0 && argc > NUMARGVS - 1)
- { /* This is the only place where argv[] can overflow */
- NUMARGVS += 100; /* Apologies, NUMARGVS is actually a variable */
- newArgv = (char **)NewPtr(sizeof(char *) * NUMARGVS);
- if (MemError() != noErr)
- return(FALSE);
- BlockMove((Ptr)argv, (Ptr)newArgv, sizeof(char *) * (NUMARGVS - 100));
- DisposPtr((Ptr)argv);
- argv = newArgv;
- }
- }
- return(TRUE);
- }
-
- /* Bail out if error during hAWK run. */
- void JumpOnHAWKError(short inputErrorNumber)
- {
-
- gInputError = inputErrorNumber;
- longjmp(envBuf, 1); /* return to save point */
- }
-
- void CleanUpAfterHAWK(void)
- {
- /* Call TFreeAll if using TMalloc etc, call FFreeAll if using Fmalloc etc
- -at present, using Fmalloc which is better on all scores. */
-
- FFreeAll();
- alloca(0);
- //DumpZoneList(); with MW dont't have this any more
-
- while (--argc >= 0)
- {
- if (argv[argc])
- DisposPtr(argv[argc]);
- }
- DisposPtr((Ptr)argv);
- DisposeProgress(); /* remove progress dialog from screen if present */
- }
-
- void HandleHAWKError()
- {
- /* -future- use gInputError */
- SysBeep(2);
- }
-
-
- static pascal void EmptyExitToShell(void);
- enum
- {
- uppExitToShellProcInfo = kPascalStackBased
- };
- // Patch ExitToShell out temporarily and call exit()
- void DoExiting(void)
- {
- pascal void (*gOldExitToShell)(void);
- UniversalProcPtr EmptyExitToShellProcPtr;
-
- gOldExitToShell = (void *)GetToolTrapAddress(0xA9F4);
- EmptyExitToShellProcPtr = NewRoutineDescriptor((ProcPtr)&EmptyExitToShell,
- uppExitToShellProcInfo,
- GetCurrentISA());
- SetToolTrapAddress(EmptyExitToShellProcPtr, 0xA9F4);
- exit(0);
- SetToolTrapAddress((UniversalProcPtr)gOldExitToShell, 0xA9F4);
- }
-
- static pascal void EmptyExitToShell(void)
- {
- ;
- }
-